//
//  TaxiPriceCalculator.cpp
//  CostFunction
//
//  Created by ss ss on 7/9/12.
//  Copyright (c) 2012 s. All rights reserved.
//

#include "TaxiPriceCalculator.h"
#include <cassert>

namespace TaxiPriceCalculator {
    struct CalcParam
    {
        int underway;
        int underwayPrice;
        int underwayPrice_night;
        double shortwayPrice;
        int longwayLine;
        double longwayAddPercent;
        double addPercent_night;
        int psPrice;
        int dayBeginHour;
        int dayEndHour;
    };
    
    CalcParam AllCityParam[] = 
    {
        {3, 13, 17, 2.4, 10, 0.5, 0.3, 1, 5, 23},
        {2, 6,  7,  1.5, 8,  0.5, 0.2, 0, 5, 23}
    };
    
    
    double CalculatePrice(double distance, City city, int hour, int minute)
    {
        double time = static_cast<double>(hour) + static_cast<double>(minute) / 60.0;
        assert( (time >= 0.0 && time < 24.0) && "time must be in [0, 24) range");
        CalcParam param = AllCityParam[city];
        
        assert((param.dayEndHour >= param.dayBeginHour) && "dayend hour must be greater than daybegin hour");
        
        //1. set price to underway price
        
        // no matter the underwayPrece is the min price;
        double price = param.underwayPrice;
        
        //2. calc night extra percent
        
        // we need get a extra percent for night, if it is not on night, then set percent to 1 (mean 100%)
        // and set price initial to underwayPrice_night
        double extraPercentOnNight = 1;
        if ( time > param.dayEndHour || time < param.dayBeginHour) {
            extraPercentOnNight = 1 + param.addPercent_night;
            price = param.underwayPrice_night;
        }
        
        //3. if destance less than underway, then we get the price, if equal the initial value of price
        if (distance <= param.underway)
            return price + param.psPrice;
        
        //4. calc short way price 
        int shortWayDistance = distance;
        if (distance > param.longwayLine) {
            int distanceThanLongWay = distance - param.longwayLine;
            double thanLongWayPrice = distanceThanLongWay * param.shortwayPrice * (1 + param.longwayAddPercent) * extraPercentOnNight;
            price += thanLongWayPrice;
            
            shortWayDistance = param.longwayLine;
        }
        
        shortWayDistance -= param.underway;
        
        double shortWayPrice = shortWayDistance * param.shortwayPrice * extraPercentOnNight;
        
        price += shortWayPrice;
        
        //5. add ps price
        price += param.psPrice;
        
        
        return price;
    }
    
}